import Event from './event.js'
import Map from './map.js'
import Food from './food.js'
import Snake from './snake.js'


export default class Game extends Event {
  constructor(el, rect) {
    super();
    this.map = new Map(el, rect);
    this.food = new Food(this.map);
    this.snake = new Snake(this.map, this.food);
    this.timer = 0;
    this.interval = 200;
    this.keyDown = this.keyDown.bind(this);
    this.grade = 0; //分数
    this.control();

    this.map.render();
  }
  // 开始游戏
  start() {
    this.move();
  }
  // 暂停游戏
  stop() {
    clearInterval(this.timer);
  }
  // 控制移动
  move() {
    this.stop();
    this.timer = setInterval(() => {
      this.snake.move();
      this.map.clearData();
      if (this.isEat()) {
        this.snake.eatFood();
        this.food.create();
        this.grade++;
        this.changeGrade(this.grade);
        this.interval *= 0.9;
        this.stop;
        this.start();
      }
      if (this.grade >= 5) {
        this.over(2)
        return;
      }
      if (this.isOver()) {
        this.over(1);
        return;
      }
      this.map.setData(this.snake.data);
      this.map.setData(this.food.data);
      this.map.render();
    }, this.interval);
  }
  // 判断是否吃到食物
  isEat() {
    return (
      this.snake.data[0].x == this.food.data.x &&
      this.snake.data[0].y == this.food.data.y
    );
  }
  changeGrade(grade) {
    this.dispatch('changeGrade', grade)
  }
  // 判断是否结束游戏
  isOver() {
    //判断蛇出图
    if (
      this.snake.data[0].x < 0 ||
      this.snake.data[0].x >= this.map.cells ||
      this.snake.data[0].y < 0 ||
      this.snake.data[0].y >= this.map.rows
    ) {
      return true;
    }
    // 判断蛇撞到自己
    for (let i = 1; i < this.snake.data; i++) {
      if (
        this.snake.data[0].x == this.snake.data[i].x &&
        this.snake.data[0].y == this.snake.data[i].y
      ) {
        return true;
      }
    }
    return false;
  }
  /**
   * 游戏结束
   * overStatus 1中途停止 2通关
   */
  over(overStatus) {
    console.log('over', overStatus)
    if (this.overStatus == 2) {
      this.dispatch("win")
    } else {
      this.dispatch("gameOver")
    }
    this.stop();
  }
  keyDown({
    keyCode
  }) {
    switch (keyCode) {
      case 37:
        this.snake.changeDir("left");
        break;
      case 38:
        this.snake.changeDir("top");
        break;
      case 39:
        this.snake.changeDir("right");
        break;
      case 40:
        this.snake.changeDir("bottom");
        break;
    }
  }
  // 控制器
  control() {
    if (this.toControl) {
      this.toControl();
      return;
    }
    window.addEventListener("keydown", this.keyDown);
  }

  addControl(fn) {
    fn.call(this)
    window.removeEventListener("keydown", this.keyDown);
  }
}